package studia.figlewicz.math.library;

import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public abstract class PrzeplywPieniezny {

	public final static String STOPA_DYSKONTA = Stale.PRZEPLYW_PIENIEZNY_STOPA_DYSKONTA;
	
	protected Date dataPrzeplywu;
	protected Double nominal;
	protected WynikWyceny wynikWyceny;
	
	protected Map<String, ZmiennaRynkowa> zmienneRynkowe = new HashMap<String, ZmiennaRynkowa>();
	protected LinkedHashMap<Date, Double> stopaDyskonta = new LinkedHashMap<Date, Double>();
	Date dataWyceny;


	// konstruktory
	public PrzeplywPieniezny(Date dataPrzeplywu, Double nominal) {
		this.dataPrzeplywu = dataPrzeplywu;
		this.nominal = nominal;
		for (String s : getInstrumentyPodstawowe()) {
			zmienneRynkowe.put(s, null);
		}
	}


	// gettery i settery
	public WynikWyceny getWynikWyceny() {
		return wynikWyceny;
	}
	public void setWynikWyceny(WynikWyceny wynikWyceny) {
		this.wynikWyceny = wynikWyceny;
	}
	public Date getDataPrzeplywu() {
		return dataPrzeplywu;
	}
	public void setDataPrzeplywu(Date dataPrzeplywu) {
		this.dataPrzeplywu = dataPrzeplywu;
	}
	public Double getNominal() {
		return nominal;
	}
	public void setNominal(Double nominal) {
		this.nominal = nominal;
	}
	public abstract String[] getInstrumentyPodstawowe();
	public Map<String, ZmiennaRynkowa> getZmienneRynkowe() {
		return zmienneRynkowe;
	}
	public ZmiennaRynkowa getZmiennaRynkowa(String instrumentPodstawowy) {
		ZmiennaRynkowa resoult = null;
		resoult = zmienneRynkowe.get(instrumentPodstawowy);
		return resoult;
	}
	public void setZmienneRynkowe(String instrumentPodstawowy, ZmiennaRynkowa zmiennaRynkowa) {
		try {
			if (! zmienneRynkowe.containsKey(instrumentPodstawowy))
				throw new Exception("Brak inetrumentu podsatwowego o nazwie '" + instrumentPodstawowy + "'.");
			zmienneRynkowe.put(instrumentPodstawowy, zmiennaRynkowa);
		}
		catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	public LinkedHashMap<Date, Double> getStopaDyskonta() {
		return stopaDyskonta;
	}
	public void setStopaDyskonta(LinkedHashMap<Date, Double> stopaDyskonta) {
		this.stopaDyskonta = stopaDyskonta;
	}
	public Date getDataWyceny() {
		return dataWyceny;
	}
	public void setDataWyceny(Date dataWyceny) {
		this.dataWyceny = dataWyceny;
	}
	public void setDyskonto(LinkedHashMap<Date, Double> stopaDyskonta, Date dataWyceny) {
		this.stopaDyskonta = stopaDyskonta;
		this.dataWyceny = dataWyceny;
	}
	
	// metody
	public abstract StatystykaWyceny obliczWyplate(Map<String, TrajektoriaProcesu> projekcje);

	protected double integral(LinkedHashMap<Date, Double> punkty, Date poczatek, Date koniec, int potega) {
		double resoult = 0;
		
		Double val1 = Utils.wartoscWygladzona(punkty, poczatek, MetodaInterpolacji.LINIOWA);
		Double val2 = Utils.wartoscWygladzona(punkty, koniec, MetodaInterpolacji.LINIOWA);
		double podsatwa = Utils.getYearFractionStandard(poczatek,koniec);
		
		if (potega > 1) {
			double srednia = 1/2 * (val1.doubleValue() + val2.doubleValue());
			double oldval1 = val1.doubleValue();
			double oldval2 = val1.doubleValue();
			for (int i=1; i<potega; i++) {
				val1 = val1.doubleValue() * oldval1;
				val2 = val2.doubleValue() * oldval2;
			}
			if (val1.doubleValue() < val2.doubleValue()) {
				resoult = podsatwa * 1/2 * (val1.doubleValue() + srednia);
				resoult = resoult + podsatwa * 1/2 * (srednia + val2.doubleValue());
			}
			else {
				resoult = podsatwa * 1/2 * (val2.doubleValue() + srednia);
				resoult = resoult + podsatwa * 1/2 * (srednia + val1.doubleValue());
			}
		}
		else
			resoult = podsatwa * 1/2 * (val1.doubleValue() + val2.doubleValue());
		
		return resoult;
	}
	

	 
}
 
